# 导入DRF的view
from rest_framework.views import APIView
# 导入序列化类
from studentweb.serializers import StudentSerializers
# 定义了DRF中封装过的Response
from rest_framework.response import Response
# 导入返回的编码
from rest_framework import status
# 导入类
from studentweb.models import Student
from django.http import HttpResponse

# ==== 说明：基于APIView实现的增删改的5个函数 ====
"""

class StudentView(APIView):
    def get(self, request, *arg, **kwargs):
        # 获取所有的学生信息
        queryset = Student.objects.all()  # queryset集合
        # 序列化Json返回
        result = StudentSerializers(instance=queryset, many=True)
        # 返回
        return Response(result.data, status=status.HTTP_200_OK)

    def post(self, request):
        # 添加学生信息
        # 前台传递数据 ---> 反序列化( Json --> dict ---> obj )【前端的数据进行校验】 --> 返回【情况01：添加成功，返回新增数据
                                                                                        # 情况02：报错，返回错误信息】
        # 1. 获取前端传递的数据，并序列化
        rec = StudentSerializers(data=request.data)
        # 2. 校验是否符合要求。
        #  要求来源于三个地方【1. models.py定义的， 2. 在序列化的时候通过字段注明约束     3. 自定义约束 】
        if rec.is_valid():
            # 所有的数据符合规范
            # 保存到数据库！
            rec.save()
            # 返回
            return Response(data=rec.data, status=status.HTTP_201_CREATED)
        # === 有字段不符合要求==
        return Response(rec.errors, status=status.HTTP_400_BAD_REQUEST)


class StudentDetailView(APIView):

    def get(self, request, *args, **kwargs):
        print(kwargs)
        # 获取单个学生详情
        try:
            student = Student.objects.get(pk=kwargs.get('pk'))
        except Student.DoesNotExist:
            return Response({'error':"没有当前学生信息！"},  status=status.HTTP_404_NOT_FOUND)

        # 把单条记录序列化
        ser_student = StudentSerializers(instance=student)
        # 返回
        return Response(ser_student.data, status=status.HTTP_200_OK)

    def put(self, request, *args, **kwargs):
        # ==== 修改所有的属性 【修改的时候需要提供所有的属性】====
        # 获取当前的对象
        try:
            student = Student.objects.get(pk=kwargs.get('pk'))
        except Student.DoesNotExist:
            return Response({'error': "没有当前学生信息！"}, status=status.HTTP_404_NOT_FOUND)

        # 序列化对象  --- 【数据的数据， 用户提交的数据】
        serializer = StudentSerializers(instance=student, data=request.data)

        # 验证提交的数据是否符合要求
        serializer.is_valid(raise_exception=True)
        # 提交修改
        serializer.save()
        # 返回
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def patch(self, request, *args, **kwargs):
        # ==== 修改部分的属性【修改的时候需要提供需要修改的属性】 ====
        # 获取当前的对象
        try:
            student = Student.objects.get(pk=kwargs.get('pk'))
        except Student.DoesNotExist:
            return Response({'error': "没有当前学生信息！"}, status=status.HTTP_404_NOT_FOUND)

        # 序列化对象  --- 【数据的数据， 用户提交的数据】
        serializer = StudentSerializers(instance=student, data=request.data, partial=True)

        # 验证提交的数据是否符合要求
        serializer.is_valid(raise_exception=True)
        # 提交修改
        serializer.save()
        # 返回
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def delete(self, request, *args, **kwargs):
        # ========== 删除 ==========
        try:
            # 获取对象并删除
            Student.objects.get(pk=kwargs.get('pk')).delete()
            # 返回
            return Response(status=status.HTTP_204_NO_CONTENT)
        except Student.DoesNotExist:
            return Response({'error': "没有当前学生信息！"}, status=status.HTTP_404_NOT_FOUND)
            
"""


# ==== 说明：基于GenericAPIView实现增删改的5个函数 ===
"""
from rest_framework.generics import GenericAPIView


class StudentView(GenericAPIView):
    # 需要提供queryset和序列化的类
    queryset = Student.objects.all()
    serializer_class = StudentSerializers

    def get(self, request):
        # ======= 实现获取所有数据 =====
        # 1. 获取所有的数据集
        queryset = self.get_queryset()
        # 2. 序列化成json格式
        serializer = self.get_serializer(instance=queryset, many=True)
        # 3. 返回
        return Response(serializer.data, status=status.HTTP_200_OK)

    def post(self, request):
        # =============== 实现添加一条数据 =========
        # 1. 获取数据并序列化
        serializer = self.get_serializer(data=request.data)
        # 2. 对数据进行校验【如果出错，页面直接展示异常】
        serializer.is_valid(raise_exception=True)
        # 3. 保存到数据
        serializer.save()
        # 4. 返回
        return Response(serializer.data, status=status.HTTP_201_CREATED)


class StudentDetailView(GenericAPIView):
    # 需要提供queryset和序列化的类
    queryset = Student.objects.all()
    serializer_class = StudentSerializers

    def get(self, request, pk):
        # ======= 实现获取单条数据 =======
        # 1. 获取相应的实例
        instance = self.get_object()
        # 2. 序列化单条记录
        serializer = self.get_serializer(instance=instance)
        # 3. 返回
        return Response(serializer.data, status=status.HTTP_200_OK)

    def put(self, request, pk):
        # ======= 实现修改某一个数据【提供全部属性】=======
        # 1. 获取当前修改的对象
        instance = self.get_object()
        # 2. 序列化对象【数据库的对象，表单提交的对象】
        serializer = self.get_serializer(instance=instance, data=request.data)
        # 3. 校验表单比较的数据
        serializer.is_valid(raise_exception=True)
        # 4. 如果校验成功，保存到数据库
        serializer.save()
        # 5. 返回给用户
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def patch(self, request, pk):
        # ======= 实现修改某一个数据【提供全部属性】=======
        # 1. 获取当前修改的对象
        instance = self.get_object()
        # 2. 序列化对象【数据库的对象，表单提交的对象】
        serializer = self.get_serializer(instance=instance, data=request.data, partial=True)
        # 3. 校验表单比较的数据
        serializer.is_valid(raise_exception=True)
        # 4. 如果校验成功，保存到数据库
        serializer.save()
        # 5. 返回给用户
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def delete(self, request, pk):
        # =======  实现删除某一条记录 =======
        # 1. 获取对象并删除
        self.get_object().delete()
        # 2. 返回给用户
        return Response(status=status.HTTP_204_NO_CONTENT)
"""


# ====说明：基于基于GenericAPIView和Mixins类实现增删改的5个函数
"""
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin


class StudentView(GenericAPIView, ListModelMixin, CreateModelMixin):
    # 指定queryset集合和序列化的类
    queryset = Student.objects.all()
    serializer_class = StudentSerializers

    def get(self, request):
        # === 实现获取所有的记录===
        return self.list(request)

    def post(self, request):
        # === 实现记录的添加 ===
        return self.create(request)

class StudentDetailView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
    # 指定queryset集合和序列化的类
    queryset = Student.objects.all()
    serializer_class = StudentSerializers

    def get(self, request, pk):
        # ==== 查看某一个记录 ===
        return self.retrieve(request, pk=pk)

    def put(self, request, pk):
        # =======修改记录 ========
        return self.update(request, pk=pk)

    def delete(self, request, pk):
        # ===== 删除记录 ==========
        return self.destroy(request, pk=pk)
"""

# === 说明：基于基于GenericAPIView和Mixins类的子类
"""

# 于GenericAPIView和Mixins类实现的代码可以继续简洁， drf在使用GenericAPIView和Mixins进行组合以后，还提供视图子类
# 试图子类是通用视图类和模型扩展类的子类， 提供了各种试图方法调用mixinx操作
# 1） ListAPIView = GenericAPIView + ListModelMixin
# 2)  CreateAPIView = GenericAPIView + CreateModelMixin
# 3)  RetrieveAPIView = GenericAPIView + RetrieveModelMixin
# 4） UpdateAPIView = GenericAPIView + RetrieveModelMixin
# 5)  DestroyAPIView = GenericAPIView + DestroyModelMixin

# ===== 以上的视图类可以组合 ====
# 1） ListCreateAPIView = ListAPIView  + CreateAPIView
# 2)  RetrieveUpdateAPIView = RetrieveAPIView + UpdateAPIView
# 3)  RetrieveDestroyAPIView = RetrieveAPIView + DestroyModelMixin
# 4)  RetrieveUpdateDestroyAPIView = GenericAPIView + RetrieveAPIView + UpdateAPIView + DestroyModelMixin

from rest_framework.generics import ListAPIView,ListCreateAPIView, RetrieveUpdateDestroyAPIView, RetrieveUpdateAPIView


class StudentView(ListCreateAPIView):
    # 指定queryset集合和序列化的类
    queryset = Student.objects.all()
    serializer_class = StudentSerializers


class StudentDetailView(RetrieveUpdateDestroyAPIView):
    # 指定queryset集合和序列化的类
    queryset = Student.objects.all()
    serializer_class = StudentSerializers
    
    
"""

# === 说明：基于视图集的实现-- Viewset ----
"""

from rest_framework.viewsets import ViewSet

class StudentView(ViewSet):

    def get_list(self, request):
        # 获取所有学生信息
        queryset = Student.objects.all()
        # 序列化数据
        serializer = StudentSerializers(instance=queryset, many=True)
        # 返回
        return Response(serializer.data, status=status.HTTP_200_OK )

    def create_data(self, request):
        # 添加学生信息
        # 前台传递数据 ---> 反序列化( Json --> dict ---> obj )【前端的数据进行校验】 --> 返回【情况01：添加成功，返回新增数据
        # 情况02：报错，返回错误信息】
        # 1. 获取前端传递的数据，并序列化
        rec = StudentSerializers(data=request.data)
        # 2. 校验是否符合要求。
        #  要求来源于三个地方【1. models.py定义的， 2. 在序列化的时候通过字段注明约束     3. 自定义约束 】
        if rec.is_valid():
            # 所有的数据符合规范
            # 保存到数据库！
            rec.save()
            # 返回
            return Response(data=rec.data, status=status.HTTP_201_CREATED)
        # === 有字段不符合要求==
        return Response(rec.errors, status=status.HTTP_400_BAD_REQUEST)

    def get_detail(self, request, *args, **kwargs):
        print(kwargs)
        # 获取单个学生详情
        try:
            student = Student.objects.get(pk=kwargs.get('pk'))
        except Student.DoesNotExist:
            return Response({'error': "没有当前学生信息！"}, status=status.HTTP_404_NOT_FOUND)

        # 把单条记录序列化
        ser_student = StudentSerializers(instance=student)
        # 返回
        return Response(ser_student.data, status=status.HTTP_200_OK)

    def update_data(self, request, *args, **kwargs):
        # ==== 修改所有的属性 【修改的时候需要提供所有的属性】====
        # 获取当前的对象
        try:
            student = Student.objects.get(pk=kwargs.get('pk'))
        except Student.DoesNotExist:
            return Response({'error': "没有当前学生信息！"}, status=status.HTTP_404_NOT_FOUND)

        # 序列化对象  --- 【数据的数据， 用户提交的数据】
        serializer = StudentSerializers(instance=student, data=request.data)

        # 验证提交的数据是否符合要求
        serializer.is_valid(raise_exception=True)
        # 提交修改
        serializer.save()
        # 返回
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def delete_data(self, request, *args, **kwargs):
        # ========== 删除 ==========
        try:
            # 获取对象并删除
            Student.objects.get(pk=kwargs.get('pk')).delete()
            # 返回
            return Response(status=status.HTTP_204_NO_CONTENT)
        except Student.DoesNotExist:
            return Response({'error': "没有当前学生信息！"}, status=status.HTTP_404_NOT_FOUND)

"""

# === 说明：基于视图集的实现-- GenericViewset ----

"""
from rest_framework.viewsets import GenericViewSet


class StudentView(GenericViewSet, ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestoryMixin):
    # 需要提供queryset和序列化的类
    queryset = Student.objects.all()
    serializer_class = StudentSerializers
"""

# === 说明：基于视图集的实现-- ReadonlyViewset ----
# ReadonlyModelViewset = GenericViewset +  ListModelMixin + RetrieveModelMixin,

"""
from rest_framework.viewsets import ReadOnlyModelViewSet
from rest_framework.mixins import RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, CreateModelMixin

class StudentView(ReadOnlyModelViewSet, CreateModelMixin, UpdateModelMixin, DestroyModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentSerializers

"""
# === 说明：基于视图集的实现-- ModelViewset ----
# ModelViewset = GenericViewset + ListModelMixin + CreateModelMixin + RetrieveModelMixin + DestroyModelMixin + UpdateModelMixin


from rest_framework.viewsets import ModelViewSet


class StudentView(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializers
